import Context from './Context.js';
import ReportTable from './table/ReportTable.js';
import SaveTool from './tools/SaveTool.js';
import AlignLeftTool from './tools/AlignLeftTool.js';
import AlignTopTool from './tools/AlignTopTool.js';
import RedoTool from './tools/RedoTool.js';
import UndoTool from './tools/UndoTool.js';
import LineTool from './tools/LineTool.js';
import BorderTool from './tools/BorderTool.js';
import BoldTool from './tools/BoldTool.js';
import ItalicTool from './tools/ItalicTool.js';
import UnderlineTool from './tools/UnderlineTool.js';
import BgcolorTool from './tools/BgcolorTool.js';
import ForecolorTool from './tools/ForecolorTool.js';
import ImageTool from './tools/ImageTool.js';
import ChartTool from './tools/ChartTool.js';
import CrosstabTool from './tools/CrosstabTool.js';
import MergeTool from './tools/MergeTool.js';
import ImportTool from './tools/ImportTool.js';
import PreviewTool from './tools/PreviewTool.js';
import FontFamilyTool from './tools/FontFamilyTool.js';
import FontSizeTool from './tools/FontSizeTool.js';
import ZxingTool from './tools/ZxingTool.js';
import SettingsTool from './tools/SettingsTool.js';
import SearchFormSwitchTool from './tools/SearchFormSwitchTool.js';
import DatasourcePanel from './panel/DatasourcePanel.js';
import PropertyPanel from './panel/PropertyPanel.js';
import SearchFormDialog from './dialog/SearchFormDialog.js';
import ImportDialog from './dialog/ImportDialog.js';
import SaveDialog from './dialog/SaveDialog.js';
import {
    undoManager, getToken, setDirty, buildNewCellDef, tableToXml, getUrlParam
} from './Utils.js';
import PrintLine from './PrintLine.js';
import {
    renderRowHeader
} from './table/HeaderUtils.js';
import { doDeleteRow } from './table/operation/DeleteRowOperation.js';
import { doDeleteCol } from './table/operation/DeleteColOperation.js';
import { doInsertRow } from './table/operation/InsertRowOperation.js';
import { doInsertCol } from './table/operation/InsertColOperation.js';
import { alert } from './MsgBox.js';
import SettingsDialog from './dialog/SettingsDialog.js';
import { updateCellsBoldStyle } from './tools/BoldTool.js';
import { updateCellsItalicStyle } from './tools/ItalicTool.js';
import { updateCellsUnderlineStyle } from './tools/UnderlineTool.js';
import { doMergeCells } from './tools/MergeTool.js';
import CrosstabDialog from './dialog/CrosstabDialog.js';
import CrossTabWidget from './widget/CrossTabWidget.js';
import Handsontable from 'handsontable';
import RowColWidthHeightDialog from './dialog/RowColWidthHeightDialog.js';
import ShortcutKeysTool from './tools/ShortcutKeysTool.js';
import { cleanCells, undoCleanCells, pasteStyle, undoPasteStyle } from './table/ContextMenu.js';

export default class UReportDesigner {
    constructor(containerId, searchFormContainerId) {
        undoManager.setLimit(100);
        const _this = this;
        this.container = $('#' + containerId);
        const flexboxContainer = $(`<div class="flex-box"></div>`)
        const mainBody = $(`<div class="main-body"></div>`)
        const mainTools = $(`<div class="main-tools"></div>`)
        const mainContainer = $(`<div class="main-container"></div>`)
        const tableContainer = $(`<div class="main-wrap"></div>`);
        const asideContainer = $('<div class="aside"></div>')
        mainBody.append(mainTools);
        mainContainer.append(tableContainer);
        mainBody.append(mainContainer);
        flexboxContainer.prepend(mainBody);
        flexboxContainer.append(asideContainer);
        this.container.append(flexboxContainer);
        getToken();//把TOKEN存入本地供预览界面使用

        // const fileInfo = '';
        this.reportTable = new ReportTable(tableContainer.get(0), function () {
            _this.context = new Context(this);
            _this.context.fileInfo = {};
            _this.context.baseInfo = {};
            _this.buildTools(_this.context);
            _this.buildTools2(_this.context, this);
            _this.datasourcePanel = new DatasourcePanel(_this.context);
            _this.propertyPanel = new PropertyPanel(_this.context);
            _this.buildPropertyPanel();
            this.value = ''
            this.bindSelectionEvent(function (rowIndex, colIndex, row2Index, col2Index) {
                _this.propertyPanel.refresh(rowIndex, colIndex, row2Index, col2Index);

                for (let tool of _this.tools) {
                    if (tool.refresh) {
                        tool.refresh(rowIndex, colIndex, row2Index, col2Index);
                    }
                }

            });
            $(document).keydown(function (event) {
                let keyCode = event.keyCode
                const hot = _this.context.hot;
                const selected = hot.getSelected();
                let startRow = selected[0],
                    startCol = selected[1],
                    endRow = selected[2],
                    endCol = selected[3];
                const rowHeight = hot.getRowHeight(startRow);
                const colWidth = hot.getColWidth(startCol);
                const dialog = new RowColWidthHeightDialog();
                let tmp = endRow;
                if (startRow > endRow) {
                    endRow = startRow;
                    startRow = tmp;
                }
                tmp = endCol;
                if (startCol > endCol) {
                    endCol = startCol;
                    startCol = tmp;
                }
                //C67 复制
                // if (event.ctrlKey && keyCode == 67) {
                //   _this.value = _this.propertyPanel.cellDef
                // }
                // //V86 粘贴
                // if (event.ctrlKey && keyCode == 86) {
                //   console.log(_this.value)
                //   _this.propertyPanel.cellDef = _this.value
                //   _this.context.hot.setDataAtCell(startRow, startCol, _this.value.value.value);
                //   setDirty();
                // }
                //Z90 撤销
                if (event.ctrlKey && keyCode == 90) {
                    if (undoManager.hasUndo()) {
                        undoManager.undo();
                    } else {
                        // alert(`${window.i18n.tools.undo.noUndo}`);
                    }
                }
                //Y89 重做
                if (event.ctrlKey && keyCode == 89) {
                    if (undoManager.hasRedo()) {
                        undoManager.redo();
                    } else {
                        alert(`${window.i18n.tools.redo.noRedo}`);
                    }
                }
                if (event.altKey && keyCode == 74) {
                    const token = getUrlParam('token')
                    // 保存
                    $("select[name=categoryId]").empty();
                    // 获取报表分类
                    $.ajax({
                        url: window._mainServer + '/api/system/DictionaryData/ReportSort/Data/Selector',
                        headers: {
                            'Authorization': token
                        },
                        success: (res) => {
                            _this.context.categoryList = res.data.list
                            const fileId = getUrlParam('id')
                            if (fileId) _this.context.baseInfo = _this.context.reportTable.baseInfo
                            const content = tableToXml(_this.context)
                            let saveDialog = new SaveDialog()
                            saveDialog.show(content, _this.context)
                        },
                        error: (response) => {
                            if (response && response.responseText) {
                                alert("服务端错误：" + response.responseText + "");
                            } else {
                                alert(`${window.i18n.dialog.save.loadFail}`);
                            }
                        }
                    });
                }
                //O79 设置（表报）
                if (event.altKey && keyCode == 79) {
                    preventDefault(event)
                    $(".data-report-modal").remove()
                    $(".modal-backdrop").remove()
                    this.settingsDialog = new SettingsDialog();
                    this.settingsDialog.show(_this.context);
                }
                //B66 加粗
                if (event.ctrlKey && keyCode == 66) {
                    preventDefault(event)
                    let oldBoldStyle = updateCellsBoldStyle(_this.context, startRow, startCol, endRow, endCol);
                    undoManager.add({
                        redo: function () {
                            oldBoldStyle = updateCellsBoldStyle(_this.context, startRow, startCol, endRow, endCol);
                            setDirty();
                        },
                        undo: function () {
                            for (let i = startRow; i <= endRow; i++) {
                                for (let j = startCol; j <= endCol; j++) {
                                    let cellDef = _this.context.getCell(i, j);
                                    if (!cellDef) {
                                        continue;
                                    }
                                    let cellStyle = cellDef.cellStyle;
                                    let bold = oldBoldStyle[i + "," + j];
                                    cellStyle.bold = bold;
                                }
                            }
                            hot.render();
                            setDirty();
                        }
                    });
                    setDirty();
                }
                //I73 倾斜
                if (event.ctrlKey && keyCode == 73) {
                    preventDefault(event)
                    let oldItalicStyle = updateCellsItalicStyle(_this.context, startRow, startCol, endRow, endCol);
                    undoManager.add({
                        redo: function () {
                            oldItalicStyle = updateCellsItalicStyle(_this.context, startRow, startCol, endRow, endCol);
                            setDirty();
                        },
                        undo: function () {
                            for (let i = startRow; i <= endRow; i++) {
                                for (let j = startCol; j <= endCol; j++) {
                                    let cellDef = _this.context.getCell(i, j);
                                    if (!cellDef) {
                                        continue;
                                    }
                                    let cellStyle = cellDef.cellStyle;
                                    let italic = oldItalicStyle[i + "," + j];
                                    cellStyle.italic = italic;
                                }
                            }
                            hot.render();
                            setDirty();
                        }
                    });
                    setDirty();
                }
                //U85 下划线
                if (event.ctrlKey && keyCode == 85) {
                    preventDefault(event)
                    let oldUnderlineStyle = updateCellsUnderlineStyle(_this.context, startRow, startCol, endRow, endCol);
                    undoManager.add({
                        redo: function () {
                            oldUnderlineStyle = updateCellsUnderlineStyle(_this.context, startRow, startCol, endRow, endCol);
                            setDirty();
                        },
                        undo: function () {
                            oldUnderlineStyle = updateCellsUnderlineStyle(_this.context, startRow, startCol, endRow, endCol, oldUnderlineStyle);
                            setDirty();
                        }
                    });
                    setDirty();
                }
                if (event.altKey && keyCode == 80) {
                    const token = getUrlParam('token')
                    let targetUrl = `${window._contextPath}/preview.html?id=preview&from=menu&token=${token}`;
                    const content = tableToXml(_this.context);
                    $.ajax({
                        url: window._server + "/designer/savePreviewData",
                        type: 'POST',
                        data: {
                            content
                        },
                        headers: {
                            'Authorization': token
                        },
                        success: function (data) {
                            // 增加后端异常处理
                            if (data && data.code !== 200) {
                                alert(`${data.msg}`);
                            } else {
                                let newWindow = window.open(targetUrl, "_blank");
                                newWindow && newWindow.focus();
                            }
                        },
                        error: function () {
                            alert(`${window.i18n.tools.preview.previewFail}`);
                        }
                    });
                }
                //1 49 斜线表头
                if (event.ctrlKey && keyCode == 49) {
                    preventDefault(event)
                    const cellDef = _this.context.getCell(startRow, startCol);
                    let oldCellData = hot.getDataAtCell(startRow, startCol);
                    let oldCellDataValue = cellDef.value;
                    const $td = $(hot.getCell(startRow, startCol));
                    $(".data-report-modal").remove()
                    $(".modal-backdrop").remove()
                    const dialog = new CrosstabDialog();
                    dialog.show(function (value) {
                        cellDef.crossTabWidget = new CrossTabWidget(_this.context, startRow, startCol, null, value);
                        hot.render();
                        setDirty();
                        Handsontable.hooks.run(hot, 'afterSelectionEnd', startRow, startCol, selected[2], selected[3]);
                        undoManager.add({
                            redo: function () {
                                oldCellData = hot.getDataAtCell(startRow, startCol);
                                oldCellDataValue = cellDef.value;
                                cellDef.crossTabWidget = new CrossTabWidget(_this.context, startRow, startCol, null, value);
                                hot.render();
                                setDirty();
                                Handsontable.hooks.run(hot, 'afterSelectionEnd', startRow, startCol, selected[2], selected[3]);
                            },
                            undo: function () {
                                cellDef.value = oldCellDataValue;
                                cellDef.crossTabWidget = null;
                                hot.setDataAtCell(startRow, startCol, oldCellData);
                                hot.render();
                                setDirty();
                                Handsontable.hooks.run(hot, 'afterSelectionEnd', startRow, startCol, selected[2], selected[3]);
                            }
                        });
                    })
                }
                // //G71 合并/拆分单元格
                // if (event.ctrlKey && keyCode == 71) {
                //   preventDefault(event)
                //   doMergeCells(startRow, startCol, endRow, endCol, hot, _this.context);
                // }
                //M77 合并/拆分单元格
                if (event.ctrlKey && keyCode == 77) {
                    let mergeCells = hot.getSettings().mergeCells || [];
                    let oldMergeCells = mergeCells.concat([]);
                    preventDefault(event)
                    doMergeCells(startRow, startCol, endRow, endCol, hot, _this.context);
                    undoManager.add({
                        redo: function () {
                            mergeCells = hot.getSettings().mergeCells || [];
                            oldMergeCells = mergeCells.concat([]);
                            doMergeCells(startRow, startCol, endRow, endCol, hot, _this.context);
                            setDirty();
                        },
                        undo: function () {
                            hot.updateSettings({ mergeCells: oldMergeCells });
                            setDirty();
                        }
                    });
                    setDirty();
                }
                //H72 设置行高
                if (event.altKey && keyCode == 72) {
                    preventDefault(event)
                    dialog.show(function (newHeight) {
                        const rowHeights = hot.getSettings().rowHeights;
                        rowHeights.splice(startRow, 1, newHeight);
                        hot.updateSettings({
                            rowHeights: rowHeights,
                            manualRowResize: rowHeights
                        });
                    }, rowHeight, false);
                    setDirty();
                }
                let pcKey = 46
                if (/(iPhone|iPad|iPod|iOS|Mac)/i.test(navigator.userAgent)) {
                    pcKey = 8
                } else if (/(Android)/i.test(navigator.userAgent)) {

                } else {
                    pcKey = 46
                }
                //L76 设置列宽
                if (event.altKey && keyCode == 76) {
                    preventDefault(event)
                    dialog.show(function (newColWidth) {
                        const colWidths = hot.getSettings().colWidths;
                        colWidths.splice(startCol, 1, newColWidth);
                        hot.updateSettings({
                            colWidths: colWidths,
                            manualColumnResize: colWidths
                        });
                    }, colWidth, true);
                    setDirty();
                }
                //清空内容del 46
                if (event.ctrlKey && keyCode == pcKey) {
                    let removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, 'content')
                    undoManager.add({
                        redo: function () {
                            removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, 'content');
                        },
                        undo: function () {
                            undoCleanCells(_this.context, startRow, endRow, startCol, endCol, removeCellsMap, 'content');
                        }
                    })
                }
                //清空格式 N 46  
                if (event.altKey && keyCode == pcKey) {
                    preventDefault(event)
                    let removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, 'style')
                    undoManager.add({
                        redo: function () {
                            removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, 'style');
                        },
                        undo: function () {
                            undoCleanCells(_this.context, startRow, endRow, startCol, endCol, removeCellsMap, 'style');
                        }
                    })
                }
                //清空所有
                if (event.shiftKey && keyCode == pcKey) {
                    preventDefault(event)
                    let removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, 'all')
                    undoManager.add({
                        redo: function () {
                            removeCellsMap = cleanCells(_this.context, startRow, endRow, startCol, endCol, 'all');
                        },
                        undo: function () {
                            undoCleanCells(_this.context, startRow, endRow, startCol, endCol, removeCellsMap, 'all');
                        }
                    })
                }
                //复制单元格样式
                if (event.shiftKey && keyCode == 67) {
                    let cell = _this.context.getCell(startRow, startCol);
                    if (!cell) {
                        alert("请先选中目标单元格！");
                        return;
                    }
                    window.__copy_cell_style__ = cell.cellStyle;
                }
                //粘贴单元格样式
                if (event.shiftKey && keyCode == 86) {
                    if (!window.__copy_cell_style__) {
                        alert('请先复制目标单元格样式');
                        return;
                    }
                    let oldCellsStyleMap = pasteStyle(_this.context, startRow, endRow, startCol, endCol);
                    undoManager.add({
                        redo: function () {
                            oldCellsStyleMap = pasteStyle(_this.context, startRow, endRow, startCol, endCol);
                        },
                        undo: function () {
                            undoPasteStyle(_this.context, startRow, endRow, startCol, endCol, oldCellsStyleMap);
                        }
                    })
                }
                //g 71 切换到查询表单设计页 
                if (event.altKey && keyCode == 71) {
                    $(".data-report-modal").remove()
                    $(".modal-backdrop").remove()
                    this.dialog = new SearchFormDialog();
                    this.dialog.show(_this.context.reportDef)
                }
                //导入Excel模版文件 E
                if (event.altKey && keyCode == 69) {
                    preventDefault(event)
                    $(".data-report-modal").remove()
                    $(".modal-backdrop").remove()
                    this.dialog = new ImportDialog();
                    this.dialog.show()
                }
                //标题行 b
                if (event.altKey && keyCode == 66) {
                    preventDefault(event)
                    for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
                        _this.context.addRowHeader(rowNumber, 'title');
                    }
                    renderRowHeader(_this.context.hot, _this.context);
                    setDirty();
                }
                //T 重复表头
                if (event.altKey && keyCode == 84) {
                    preventDefault(event)
                    for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
                        _this.context.addRowHeader(rowNumber, 'headerrepeat');
                    }
                    renderRowHeader(_this.context.hot, _this.context);
                    setDirty();
                }
                //W 重复表尾
                if (event.altKey && keyCode == 87) {
                    preventDefault(event)
                    for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
                        _this.context.addRowHeader(rowNumber, 'footerrepeat');
                    }
                    renderRowHeader(_this.context.hot, _this.context);
                    setDirty();
                }
                //Z 总结行
                if (event.altKey && keyCode == 90) {
                    preventDefault(event)
                    for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
                        _this.context.addRowHeader(rowNumber, 'summary');
                    }
                    renderRowHeader(_this.context.hot, _this.context);
                    setDirty();
                }
                //Q 取消行类型
                if (event.altKey && keyCode == 81) {
                    preventDefault(event)
                    for (let rowNumber = startRow; rowNumber <= endRow; rowNumber++) {
                        _this.context.adjustDelRowHeaders(rowNumber);
                    }
                    renderRowHeader(_this.context.hot, _this.context);
                    setDirty();
                }
                // 删除行 R
                if (event.altKey && keyCode == 82) {
                    preventDefault(event)
                    doDeleteRow.call(_this.context.hot);
                }
                //删除列 C
                if (event.altKey && keyCode == 67) {
                    preventDefault(event)
                    doDeleteCol.call(_this.context.hot);
                }
                //插入图片 I
                if (event.altKey && keyCode == 73) {
                    let tmp = endRow;
                    if (startRow > endRow) {
                        endRow = startRow;
                        startRow = tmp;
                    }
                    tmp = endCol;
                    if (startCol > endCol) {
                        endCol = startCol;
                        startCol = tmp;
                    }
                    let oldCellDef = _this.context.getCell(startRow, startCol);
                    let oldCellData = hot.getDataAtCell(startRow, startCol);
                    let newCellDef = buildNewCellDef(startRow + 1, startCol + 1);
                    newCellDef.value = {
                        type: 'image',
                        source: 'text',
                        value: ''
                    };
                    _this.context.addCell(newCellDef);
                    const imagePath = './icons/image.svg';
                    const image = $(`<img src="${imagePath}" width="20px">`);
                    let $td = $(hot.getCell(startRow, startCol));
                    $td.empty();
                    $td.append(image);
                    setDirty();
                    Handsontable.hooks.run(hot, 'afterSelectionEnd', startRow, startCol, endRow, endCol);

                    undoManager.add({
                        redo: function () {
                            oldCellDef = _this.context.getCell(startRow, startCol);
                            oldCellData = hot.getDataAtCell(startRow, startCol);
                            newCellDef = buildNewCellDef(startRow + 1, startCol + 1);
                            newCellDef.value = {
                                type: 'image',
                                source: 'text',
                                value: ''
                            };
                            _this.context.addCell(newCellDef);
                            hot.setDataAtCell(startRow, startCol, '');
                            hot.render();
                            setDirty();
                            Handsontable.hooks.run(hot, 'afterSelectionEnd', startRow, startCol, endRow, endCol);
                        },
                        undo: function () {
                            _this.context.addCell(oldCellDef);
                            hot.setDataAtCell(startRow, startCol, oldCellData);
                            hot.render();
                            setDirty();
                            Handsontable.hooks.run(hot, 'afterSelectionEnd', startRow, startCol, endRow, endCol);
                        }
                    });

                }
                //向上插入
                if (event.altKey && keyCode == 38) {
                    preventDefault(event)
                    doInsertRow.call(_this.context.hot, true);
                }
                //向下插入
                if (event.altKey && keyCode == 40) {
                    preventDefault(event)
                    doInsertRow.call(_this.context.hot);
                }
                //向左插入
                if (event.altKey && keyCode == 37) {
                    preventDefault(event)
                    doInsertCol.call(_this.context.hot, true);
                }
                //向右插入
                if (event.altKey && keyCode == 39) {
                    preventDefault(event)
                    doInsertCol.call(_this.context.hot);
                }
            });
            _this.printLine = new PrintLine(_this.context);
            const rows = _this.context.reportDef.rows;
            for (let row of rows) {
                const band = row.band;
                if (!band) {
                    continue;
                }
                _this.context.addRowHeader(row.rowNumber - 1, band);
            }
            renderRowHeader(_this.context.hot, _this.context);

            function preventDefault(event) {
                event.preventDefault()
                event.keyCode = false
            }
        });
    }

    buildPropertyPanel() {
        const propContainerId = '_prop_container';
        const dsContainerId = '_datasource_container';
        const propertyPanel = $('<div class="ud-property-panel jnpf-data-panel"></div>');

        $('.aside').append(propertyPanel);

        const propertyTab = $(`<ul class="nav nav-tabs">
            <li class="active">
                <a href="#${propContainerId}" data-toggle="tab" id="__prop_tab_link">${window.i18n.panel.property}</a>
            </li>
            <li>
                <a href="#${dsContainerId}" data-toggle="tab">${window.i18n.panel.datasource}</a>
            </li>
        </ul>`);

        propertyPanel.append(propertyTab);

        propertyTab.mousedown(function (e) {
            e.preventDefault();
        });
        const tabContent = $(`<div class="tab-content">`);
        const propContainer = $(`<div id="${propContainerId}" class="tab-pane fade in active jnpf-property"></div>`);
        const dsContainer = $(`<div id="${dsContainerId}" class="tab-pane fade"></div>`);
        tabContent.append(propContainer);
        tabContent.append(dsContainer);
        propContainer.append(this.propertyPanel.buildPanel());
        dsContainer.append(this.datasourcePanel.buildPanel());
        propertyPanel.append(tabContent);
    }

    buildTools(context) {
        const toolbar = $(`
            <div class="top-toolbar">
                <div class="logo"><img src="logo.png" /><span> · 报表设计</span></div>
                <div class="options">
                    <button class="el-button el-button--primary el-button--small top-save-btn">保 存</button>
                    <button class="el-button el-button--default el-button--small top-close-btn">关 闭</button>
                </div>
            </div>
        `);
        this.container.prepend(toolbar);
    }

    buildTools2(context, reportTable) {
        const toolbar = $(`
            <div class="top-toolbar">
                <div class="top-tools"></div>
            </div>
        `);
        $('.main-tools').prepend(toolbar);
        this.tools = [];
        this.tools.push(new UndoTool(context));
        this.tools.push(new RedoTool(context));
        this.tools.push(new SaveTool(context));
        this.tools.push(new LineTool(context));
        this.tools.push(new MergeTool(context));
        this.tools.push(new AlignLeftTool(context));
        this.tools.push(new AlignTopTool(context));
        this.tools.push(new BorderTool(context));
        this.tools.push(new FontFamilyTool(context));
        this.tools.push(new FontSizeTool(context));
        this.tools.push(new BoldTool(context));
        this.tools.push(new ItalicTool(context));
        this.tools.push(new UnderlineTool(context));
        this.tools.push(new BgcolorTool(context));
        this.tools.push(new ForecolorTool(context));
        this.tools.push(new LineTool(context));
        this.tools.push(new CrosstabTool(context));
        this.tools.push(new ImageTool(context));
        // this.tools.push(new ZxingTool(context));
        this.tools.push(new ChartTool(context));
        this.tools.push(new ImportTool(context, reportTable));
        this.tools.push(new SettingsTool(context));
        this.tools.push(new SearchFormSwitchTool(context));
        this.tools.push(new PreviewTool(context));
        this.tools.push(new ShortcutKeysTool(context));
        // this.tools.push(`<div class="options">button</div>`)
        for (const tool of this.tools) {
            $('.top-tools').append(tool.buildButton());
        }
    }
}
